package com.lsiyun.sync_file.old;

import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

// TIP 要<b>运行</b>代码，请按 <shortcut actionId="Run"/> 或
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
public class Client {

    public static final int BUFFER_SIZE = 1024 * 1024 * 20;

    public static void main(String[] args) throws Exception {
//        //TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
//        // 查看 IntelliJ IDEA 建议如何修正。
//        System.out.printf("Hello and welcome!");
//
//        for (int i = 1; i <= 5; i++) {
//            //TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
//            // 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
//            System.out.println("i = " + i);
//        }

        String origPath = "F:\\A";

        // 复制开始

        // 原文件夹下所有文件
        File origFile = new File(origPath);


//        copyFile(origFile, objFile);


        Socket socket = new Socket("localhost", 8888);

        socket.getOutputStream().write(0);
        NetFile netFile = (NetFile) new ObjectInputStream(socket.getInputStream()).readObject();

        while (true) {
            System.out.println("开始同步：" + new SimpleDateFormat("yyyy-MM-dd_hh:mm:ss.sss").format(new Date()));
            // com.lsiyun.sync_file.old.NetFile netFile = new com.lsiyun.sync_file.old.NetFile(objFile.getPath(), socket);
            sync(origFile, netFile, socket);
            System.out.println("同步结束：" + new SimpleDateFormat("yyyy-MM-dd_hh:mm:ss.sss").format(new Date()));
            Thread.sleep(1000 * 10);
        }
    }

    /**
     * 同步两个文件夹。这两个目录要求已存在
     *
     * @param dir      目录
     * @param otherDir 另外一个目录
     */
    private static void sync(File dir, NetFile otherDir, Socket socket) throws Exception {
        syncA2B(dir, otherDir, socket);
        // syncA2B(otherDir, dir);
    }

    public static void syncA2B(File dir, NetFile otherDir, Socket socket) throws Exception {
        if (dir == null || otherDir == null || !dir.exists() || !otherDir.exists() || !dir.isDirectory() || !otherDir.isDirectory()) {
            throw new Exception("同步目录有问题");
        }

        File[] dirFiles = dir.listFiles();
        NetFile[] otherDirFiles = otherDir.listFiles(socket);

        for (File dirFile : dirFiles) {
            boolean hasSameNameFile = false;
            for (NetFile otherDirFile : otherDirFiles) {
                if (dirFile.getName().equals(otherDirFile.getName())) {
                    // 同名
                    if (dirFile.isFile() && otherDirFile.isFile()) {
                        // 都是文件
                        hasSameNameFile = true;
                        long modifiedTime = dirFile.lastModified();
                        long otherModifiedTime = otherDirFile.lastModified();
                        if (modifiedTime > otherModifiedTime) {
                            otherDirFile.delete(socket);
                            copyFile(dirFile, otherDirFile, socket);
                            otherDirFile.setLastModified(socket, modifiedTime);
                        }
                    } else if(dirFile.isDirectory() && otherDirFile.isDirectory()){
                        // 都是文件夹
                        syncA2B(dirFile, otherDirFile, socket);
                    }

//                    else if (modifiedTime < otherModifiedTime) {
//                        copyFile(otherDirFile, dirFile);
//                    }

                    break;
                }
            }
            if (!hasSameNameFile) {
                copyFile(dirFile, new NetFile(otherDir, dirFile.getName()), socket);
            }
        }
    }

    /**
     * 复制文件或文件夹
     *
     * @param orig 源文件
     * @param obj  目标文件
     */
    private static void copyFile(File orig, NetFile obj, Socket socket) throws Exception {
        // 判断是文件还是目录
        if (orig.isFile()) {
            if (obj.exists()) {
                return;
            }

            // 直接拷贝
            FileInputStream inputStream = new FileInputStream(orig);
            OutputStream outputStream = socket.getOutputStream();

            byte[] bs = new byte[BUFFER_SIZE];
            int n;
            while ((n = inputStream.read(bs)) >= 0) {
                outputStream.write(bs, 0, n);
            }

            inputStream.close();
            outputStream.close();
        } else {
            // 源文件是目录
            obj.mkdirs(socket);

            File[] files = orig.listFiles();

            for (File file : files) {
                copyFile(file, new NetFile(obj, file.getName()), socket);
            }
        }
    }
}